#!/usr/bin/env python
# -*- coding: utf-8 -*-
# datetime: 17/12/2023 下午10:30
# Author: name
# File: run_test_case.py
# ide: PyCharm
# description:
import asyncio
import json
import os
import time

import requests
import ruamel.yaml
import jmespath
import pytest
import yaml
from pywebio.output import *
from pywebio.pin import put_select, put_file_upload, pin, put_textarea, pin_update

from backend.app.config import HOST
from commons.comms import is_not_empty
from commons.json_tools import read_file, write_to_file
from frontend.menus import show_menus

test_suite_temp_path = "frontend/templates/test_suite.pytemp"
test_step_temp_path = "frontend/templates/test_step.pytemp"
setup_temp_path = "frontend/templates/setup.pytemp"
teardown_temp_path = "frontend/templates/teardown.pytemp"


def get_case_group():
    pass
    return ""


def get_environment_json():
    result = requests.get(HOST + "/environment/list")
    print(result.text)
    address_list = jmespath.search("@[].address", result.json())
    data_list = []
    for x, y in zip(address_list, result.json()):
        data_list.append((x, y))
    return data_list, result.json()


def create_test_case(yml_case_file_list: list):
    # print(yml_case_file_list)
    test_case_dir = f"autotest/{int(time.time() * 1000)}"
    os.mkdir(test_case_dir)
    for yml_case_data in yml_case_file_list:
        print(yml_case_data)
        yml_case = yaml.load(yml_case_data["content"], Loader=yaml.UnsafeLoader)
        py_file_name = yml_case_data["filename"].split(".")[0]
        print(yml_case)
        test_suite_temp = read_file(test_suite_temp_path)
        print(test_suite_temp)
        test_suite_temp = test_suite_temp.replace("{{suite_name}}", py_file_name).replace("{{suite_desc}}",
                                                                                          yml_case[
                                                                                              "suite_desc"])
        write_to_file(f"{test_case_dir}/test_{py_file_name}.py", test_suite_temp, "a")
        for case in yml_case["test_steps"]:
            """
                参数处理需要在发送请求之前处理,否则,动态提取的参数无法在第一时间进行获取到
            """
            # case = handle_params(json.dumps(case, ensure_ascii=False))
            case["request"]["url"] = case["request"]["url"]
            print("转化后的参数", case)
            setup_temp = read_file(setup_temp_path)
            teardown_temp = read_file(teardown_temp_path)
            test_step_temp = read_file(test_step_temp_path)
            if case["request"].get("setup"):
                write_to_file(f"{test_case_dir}/test_{py_file_name}.py", setup_temp, "a")
            if case["request"].get("teardown"):
                write_to_file(f"{test_case_dir}/test_{py_file_name}.py", teardown_temp, "a")
            test_step_temp = test_step_temp.replace("{{step_desc}}", case["step_desc"]).replace("{{case_info}}",
                                                                                                str([case])).replace(
                "{{step_name}}",

                case["step_name"].replace("${", "").replace("}$", "") if "${" in case["step_name"] else case[
                    "step_name"])
            write_to_file(f"{test_case_dir}/test_{py_file_name}.py", test_step_temp, "a")


def business_exec_case():
    yml_test_case_list = is_not_empty(pin.yml_case_files, "测试用例文件")

    print(yml_test_case_list)
    if yml_test_case_list:
        popup('用例执行', [
            put_textarea("run_test_case_result", rows=5, value="用例执行中请稍后", readonly=True),
            put_button("关闭", onclick=lambda: close_popup(),small=True,color="dark"),
        ], size=PopupSize.LARGE, closable=False)
        environment_json = pin.run_environment
        print(environment_json)
        test_case_dir_name = int(time.time() * 1000)
        test_case_dir = f"autotest/{test_case_dir_name}"
        os.mkdir(test_case_dir)
        result = requests.get(HOST + f"/login/{environment_json.get('login_temp_id')}")
        print(result.json())
        # create_test_case(yml_test_case_list)
        # 根据登录模板生成对应的config.py文件
        host = environment_json["address"]
        username = environment_json["username"]
        password = environment_json["password"]
        login_temp = str(result.json()["login_temp"]).replace("${host}$", host).replace("${username}$",
                                                                                        username).replace(
            "${password}$", password)
        write_to_file(f"{test_case_dir}/conftest.py", login_temp, "a")

        # 生成测试用例文件

        for yml_case_data in yml_test_case_list:
            print(yml_case_data)
            yml_case = yaml.load(yml_case_data["content"], Loader=yaml.UnsafeLoader)
            py_file_name = yml_case_data["filename"].split(".")[0]
            print(yml_case)
            test_suite_temp = read_file(test_suite_temp_path)
            print(test_suite_temp)
            test_suite_temp = test_suite_temp.replace("{{suite_name}}", py_file_name).replace("{{suite_desc}}",
                                                                                              yml_case[
                                                                                                  "suite_desc"])
            write_to_file(f"{test_case_dir}/test_{py_file_name}.py", test_suite_temp, "a")
            for case in yml_case["test_steps"]:
                """
                    参数处理需要在发送请求之前处理,否则,动态提取的参数无法在第一时间进行获取到
                """
                # case = handle_params(json.dumps(case, ensure_ascii=False))
                case["request"]["path"] = case["request"]["path"]
                print("转化后的参数", case)
                setup_temp = read_file(setup_temp_path)
                teardown_temp = read_file(teardown_temp_path)
                test_step_temp = read_file(test_step_temp_path)
                if case["request"].get("setup"):
                    write_to_file(f"{test_case_dir}/test_{py_file_name}.py", setup_temp, "a")
                if case["request"].get("teardown"):
                    write_to_file(f"{test_case_dir}/test_{py_file_name}.py", teardown_temp, "a")

                test_step_temp = test_step_temp.replace("{{step_desc}}", case["step_desc"]).replace("{{step_name}}",
                                                                                                    case["step_name"])
                del case["step_desc"]
                del case["step_name"]
                test_step_temp = test_step_temp.replace("{{case_info}}", str([case]))
                write_to_file(f"{test_case_dir}/test_{py_file_name}.py", test_step_temp, "a")
                write_to_file(f"{test_case_dir}/__init__.py", "", "w")

            # pytest.main(['-vs', f'--alluredir=./{test_case_dir}/allure/temp', '--clean-alluredir', '--pyargs',f'./{test_case_dir}/'])
            os.system(f"pytest {test_case_dir} -vs --alluredir=./{test_case_dir}/allure/temp")
            os.system(f"allure generate {test_case_dir}/allure/temp -o ./{test_case_dir}/allure/report")
            report_url=f"http://127.0.0.1:8081/reports/{test_case_dir_name}/allure/report/"

            # 将数据写入到数据库中
            response = requests.post(HOST + "/report/add", json={"url":report_url})
            print(response.text)
            if response.json()["code"]==200:
                pin_update("run_test_case_result",
                           value=f"用例执行成功，测试报告:\n {report_url}")
            else:
                pin_update("run_test_case_result",
                           value=f"用例执行失败，测试报告生成失败")




def html_case_exec():
    """
        执行用例

        执行用例的流程
        1. 获取所有的yml用例文件
        2. 将yml用例文件生成对应的py文件
        3. 执行pytest运行测试命令
        4. 生成测试报告

    """
    show_menus()
    case_group = get_case_group()
    environment, environment_json = get_environment_json()
    put_tabs(
        [
            {
                "title": "用例执行",
                "content": [
                    put_html("<hr>"),
                    put_html("<h3>执行信息</h3>"),
                    put_row([
                        None,
                        put_text("运行环境"),
                        put_select("run_environment", environment, help_text="请选择运行环境"),
                        None
                    ], size="10% 10% 50%"),
                    put_html("<br>"),
                    put_row([
                        None,
                        put_text("上传测试用例"),
                        put_file_upload("yml_case_files", placeholder="请选择测试用例", accept=[".yml", ".yaml"],
                                        multiple=True),
                        None
                    ], size="10% 10% 50% 5%"),
                    put_html("<br>"),
                    put_row([
                        None,
                        None,
                        None,
                        put_button("执行", onclick=lambda: business_exec_case()),
                    ], size="10% 10% 55% 5%"
                    )

                ]
            }
        ], scope="data_list"
    )
